package com.yenlien.traceyun.business.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.business.dao.BaseSoilDao;
import com.yenlien.traceyun.business.dao.BaseSoilEquipmentDao;
import com.yenlien.traceyun.business.dao.EquipmentDao;
import com.yenlien.traceyun.business.dao.SensorCodeDao;
import com.yenlien.traceyun.business.entity.BaseSoil;
import com.yenlien.traceyun.business.entity.BaseSoilEquipment;
import com.yenlien.traceyun.business.entity.Equipment;
import com.yenlien.traceyun.business.entity.SensorCode;
import com.yenlien.traceyun.common.utils.HttpUtil;
import com.yenlien.traceyun.webase.exception.BusinessException;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.*;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by LiuSha on 2020/7/28.
 */
@Service
public class EquipmentService {
    @Autowired
    private EquipmentDao equipmentDao;

    @Autowired
    private BaseSoilEquipmentDao baseSoilEquipmentDao;

    @Autowired
    private SensorCodeDao sensorCodeDao;


    @Autowired
    private BaseSoilDao baseSoilDao;

    public Page<Equipment> findByList(final Equipment equipment) {
        Pageable pageable = PageRequest.of(equipment.getPage(), equipment.getPageSize(), Sort.Direction.DESC, "createtime");
        return equipmentDao.findAll(new Specification<Equipment>() {
            private static final long serialVersionUID = 1L;

            @Override
            public Predicate toPredicate(Root<Equipment> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Path<String> companyId = root.get("companyId");
                //构造查询条件
                List<Predicate> list = new ArrayList<>();
                if (!StringUtils.isEmpty(equipment.getCompanyId())) {
                    list.add(cb.equal(companyId, equipment.getCompanyId()));
                }
                if (!StringUtils.isEmpty(equipment.getName())) {
                    list.add(cb.equal(root.get("name"), "%" + equipment.getName() + "%"));
                }
                Predicate[] predicate = new Predicate[list.size()];
                return cb.and(list.toArray(predicate));
            }
        }, pageable);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public void save(Equipment equipment) {
        //修改
        if (!StringUtils.isEmpty(equipment.getId())) {
            baseSoilEquipmentDao.updateByEquipmentId(equipment.getType(), equipment.getName(), equipment.getId());
        }
        if("摄像头".equals(equipment.getType())){
            equipment.setType("摄像机");
        }
        equipmentDao.save(equipment);
    }


    public List<Equipment> getByAppId(String appId) {
        return equipmentDao.getByAppId(appId);
    }

    public void update(Equipment equipment) {
        equipmentDao.save(equipment);
    }

    public Equipment findById(String id) {
        Equipment equipment = equipmentDao.findById(id);
        if (!StringUtils.isEmpty(equipment.getAppKey()) && !StringUtils.isEmpty(equipment.getAppSecret())) {
            // 获取token
            Map<String, String> map = new HashMap<>();
            map.put("appKey", equipment.getAppKey());
            map.put("appSecret", equipment.getAppSecret());
            String result = HttpUtil.post("https://open.ys7.com/api/lapp/token/get", map);
            String accessToken = "";
            try {
                accessToken = JSONObject.parseObject(JSONObject.parseObject(result).get("data").toString()).get("accessToken").toString();
            }catch (Exception e){

            }
            equipment.setAccessToken(accessToken);
        }
        return equipment;
    }



    public Equipment getById(String id) {
        return equipmentDao.findById(id);
    }

    public Equipment findBySerialAndCompanyId(String serial, String compId) {
        return equipmentDao.findBySerialAndCompanyId(serial, compId);
    }


    public void delById(String id) {
        BaseSoilEquipment baseSoilEquipment = baseSoilEquipmentDao.getBaseIdByEquId(id);
        if(!Objects.isNull(baseSoilEquipment)){
            baseSoilDao.deleteById(baseSoilEquipment.getBaseSoilId());
            baseSoilEquipmentDao.deleteById(baseSoilEquipment.getId());
        }
        equipmentDao.deleteById(id);
    }





    public void delete(String id) {
        int bindnum = baseSoilEquipmentDao.countByEquipmentId(id);
        if (bindnum > 0) {
            throw new BusinessException("500", "设备已绑定地块信息删除失败");
        }
        equipmentDao.deleteById(id);
    }

    public List<Equipment> findAll(String companyId) {
        List<Equipment> list = new ArrayList<>();
        if (!StringUtils.isEmpty(companyId)) {
            list =  equipmentDao.findByCompanyId(companyId);
        }else {
            list =  equipmentDao.findAll();
        }
        return list.stream().filter(x -> !StringUtils.isEmpty(x.getCoordinate()) && !"VR".equals(x.getType())).collect(Collectors.toList());
    }


    public List<Equipment> findByCompanyIdAndType(String companyId, String type, String name) {
        if("摄像头".equals(type))
            type = "摄像机";
        if (!StringUtils.isEmpty(type) && !StringUtils.isEmpty(name)) {
            return equipmentDao.findByCompanyIdAndTypeAndName(companyId, type, name);
        }
        if (StringUtils.isEmpty(type) && !StringUtils.isEmpty(name)) {
            return equipmentDao.findByCompanyIdAndName(companyId, name);
        }
        if (StringUtils.isEmpty(type) && StringUtils.isEmpty(name)) {
            return findAll(companyId);
        }
        return equipmentDao.findByCompanyIdAndType(companyId, type);
    }

    /**
     * @param Id
     * @return
     */
    public Object findByWeather(String Id) {
        BaseSoil byId = baseSoilDao.findById(Id).get();
        String principalId = byId.getPrincipalId();
        List<String> nodeTypes = new ArrayList<>();
        if (principalId.equals("200916J01S01")) {
            nodeTypes.add("200916J01S00100");
            nodeTypes.add("200916J01S00101");
            nodeTypes.add("200916J01S00102");
            nodeTypes.add("200916J01S00103");
            nodeTypes.add("200916J01S00104");
            nodeTypes.add("200916J01S00105");
            nodeTypes.add("200916J01S00106");
        } else if (principalId.equals("200916J01S02")) {
            nodeTypes.add("200916J01S00100");
            nodeTypes.add("200916J01S00101");
            nodeTypes.add("200916J01S00102");
            nodeTypes.add("200916J01S00103");
            nodeTypes.add("200916J01S00104");
            nodeTypes.add("200916J01S00105");
            nodeTypes.add("200916J01S00106");
        }

        for (String s : nodeTypes) {
            String loginUrl = "http://kebaidata.com/userLogin";
            String getUrl2 = "http://kebaidata.com/warn/getEchartsData";
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(loginUrl);
            try {
                JSONObject loginParam = new JSONObject();
                loginParam.put("username", "htrj");
                loginParam.put("password", "htrj123");
                httpPost.addHeader("charset", "UTF-8");
                HttpEntity httpEntity = null;
                httpEntity = new StringEntity(loginParam.toJSONString(), "UTF-8");
                httpPost.setHeader("Content-Type", "application/json; charset=utf-8");
                httpPost.setEntity(httpEntity);
                CloseableHttpResponse response = httpClient.execute(httpPost);
                String loginresult = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
                //第一步完成
                //第二步
                CloseableHttpClient client3 = HttpClients.createDefault();
                List<NameValuePair> nvps2 = new ArrayList<NameValuePair>();
                nvps2.add(new BasicNameValuePair("sensorcode", s));
                URIBuilder builder = new URIBuilder(getUrl2);
                builder.setParameters(nvps2);
                HttpGet get21312 = new HttpGet(builder.build());
                response = client3.execute(get21312);
                String sdf = EntityUtils.toString(response.getEntity(), "UTF-8");
                if (sdf == "-1") {
                    new BusinessException("数据传输错误");
                }
                JSONArray jsonObject = JSONArray.parseArray(sdf);
                JSONObject o = (JSONObject) jsonObject.get(0);
                SensorCode sensorCode = new SensorCode();
                sensorCode.setNodeName((String) o.get("nodename"));
                JSONArray jsonArray = (JSONArray) o.get("timedata");
                Date date = (Date) jsonArray.get(jsonArray.size() - 1);
                sensorCode.setTimeData(date);
                sensorCode.setSensorName((String) o.get("sensorname"));
                sensorCode.setUnitData((String) o.get("unitdata"));
                JSONArray jsonArray1 = (JSONArray) o.get("valdata");
                String s1 = (String) jsonArray1.get(jsonArray1.size() - 1);
                sensorCode.setValData(s1);
                sensorCode.setSensorCode(s);
                sensorCodeDao.save(sensorCode);
            } catch (Exception e) {

            } finally {
                //释放链接
                try {
                    httpClient.close();
                } catch (IOException e) {
                }
            }
        }
        Map<String, String> map = new HashMap<>();
        for (String s1 : nodeTypes) {
            SensorCode firstBySensorCode = sensorCodeDao.findFirstBySensorCode(s1);
            String sensorName = firstBySensorCode.getSensorName();
            String valData = firstBySensorCode.getValData();
            String unitData = firstBySensorCode.getUnitData();
            map.put(sensorName, valData + unitData);
        }
        return map;
    }


    public Object findTime(Date startTime, Date endTime, String id) {
        return sensorCodeDao.findByNodeTypeAndTimeDataBetween(id, startTime, endTime);
    }

    /**
     * 根据厂商获取设备信息
     *
     * @return
     */
    public List<Equipment> findByManufacturer(String manufacturer) {
        return equipmentDao.findByManufacturer(manufacturer);
//        return equipmentDao.findXCXFX();
//        return equipmentDao.findXCKB();
    }



    /**
     * 根据设备ID获取对应信息
     */
    public List<BaseSoilEquipment> getEquipmentBaseSoil(List<String> equmentIds) {
        return baseSoilEquipmentDao.getEquipmentBaseSoil(equmentIds);
    }

    public List<JSONObject> getEquipment(String manufacturer, String type) {
        return equipmentDao.getEquipment(manufacturer, type);
    }

    public List<Equipment> findByCompanyId(String companyId) {
        return equipmentDao.findByCompanyId(companyId);
    }

    public Equipment findByDevId(String devId) {
        return equipmentDao.findById(devId);
    }

    public List<Equipment> findByTypeAndCompanyId(String type, String companyId) {
        return equipmentDao.findByTypeAndCompanyId(type, companyId);
    }

    public List<Equipment> getByDeGe() {
        return equipmentDao.getByDeGe();
    }

    public List<Equipment> getByDeGeAndType(String type) {
        return equipmentDao.getByDeGeAndType(type);
    }

    public List<Equipment> findByPCompanyIdAndType(String companyId, String type) {
        return equipmentDao.findByPCompanyIdAndType(companyId, type);
    }

    public List<Equipment> findAll() {
        return equipmentDao.findAll();
    }

    public Long cntNotVr() {
        return equipmentDao.cntNotVr();
    }

    public List<Equipment> findEquipment() {
        return equipmentDao.findEquipment();
    }
}
